/**
 * web3常用方法封装 请求
 * @author klmt. 
 **/
const {
	Common,
	Chain,
	Hardfork
} = require("@ethereumjs/common");
const contractAddress = "0x55d398326f99059fF775485246999027B3197955" //USDT合约
const contractRUTAddress = "0xbebcee45341054fa0118f2399c17ed448017b2d6" //RHD合约
import Web3, {
	utils
} from 'web3';
import useWallet from '@/common/useWallte';
import yui from '@/common/httpRequest';
import {
	USDT_ABI
} from '@/common/web3/usdt_abi.js';
import {
	RUT_ABI
} from '@/common/web3/rut_abi.js';
const {
	onConnect,
	connected,
	userAddress,
	chainId,
	networkId,
	resetApp,
	assets,
	getAccountAssets,
	web3Modal,
} = useWallet();
/* 获取当前浏览器信息 */
const web3 = new Web3(window.web3.currentProvider);
const walletAddress = yui.getWallet()
const web3Rpc = {
	/* 链接钱包状态 */
	/* 链接钱包 */
	async handleWalletConnect() {
		/* 是否链接了钱包*/
		// console.log(yui.getWallet().address)
		// if (yui.getWallet().address) {
		// 	/* 直接跳过*/
		// 	let address = yui.getWallet()
		// 	return this.truncateWithAsterisk(address.address);
		// } else {
			
			let rdatas = await onConnect().then(res => {
				if (res && userAddress.value) {
					/* 链接了钱包 */
					let walletData = {
						'address': userAddress.value,
						'walletConact': true
					};
					yui.setWallet(walletData);
					return res;
				} else {
					yui.setWallet();
					return false
				}
			}).catch(err => {
				console.log('错误信息' + err)
			})
			return rdatas
		// }

	},
	uint8ToHex: function(uint8arr) {
		let hexStr = "";
		for (let i = 0; i < uint8arr.length; i++) {
			let hex = uint8arr[i].toString(16);
			hex = hex.length === 1 ? "0" + hex : hex; // 需要补0
			hexStr += hex;
		}
		return hexStr;
	},

	contract_call: function(txObject, call_back = null) {
		if (call_back == null) {
			call_back = function(txHash) {
				console.log('txHash:', txHash)
			}
		}

		let address = yui.getWallet()
		web3.eth.getTransactionCount(address.address).then((txCount) => {
			web3.eth.estimateGas(txObject).then((gaslimit) => {

				txObject['nonce'] = web3.utils.toHex(txCount)
				txObject['gasLimit'] = web3.utils.toHex(gaslimit)
				txObject['gasPrice'] = web3.utils.toHex(web3.utils.toNumber(web3.utils.toWei(
					'10', 'gwei')))
				const common = new Common({
					chain: Chain.Mainnet,
					hardfork: Hardfork.Istanbul
				})
				const tx = LegacyTransaction.fromTxData(txObject, {
					common
				})
				signedTx = tx.sign(your_private_key)
				const serializedTx = signedTx.serialize()
				const tes = serializedTx.valueOf()
				const raw = '0x' + uint8ToHex(tes)
				web3.eth.sendSignedTransaction(raw).then(call_back)
			});
		})
	},
	/*
	    获取指定账户的eth余额
	    your_wallet_address: 指定账户地址
	    :return:账户余额,异步获取
		
	*/
	getTokenBalance() {
		let address = yui.getWallet()
		let balance = new Promise(resolve => {
			web3.eth.getBalance(address.address).then((wei) => {
				// 余额单位从wei转换为ether
				resolve(web3.utils.fromWei(wei, 'ether'))
			})
		})
		return balance
	},
	/*检测节点是否同步*/
	getEtfIsSyncing() {
		web3.eth.isSyncing().then((result) => {

			console.log("syning: " + result)
		})
	},
	/* 监听节点是否正常*/
	getNetIsListening() {
		web3.eth.net.isListening().then((result) => {
			console.log("节点监听: " + result)
		})
	},
	/*
	    获取指定账户的erc20代币余额
	    erc20_address：erc20合约地址
	    owner_address： 指定账户地址
	    :return:账户erc20代币余额
	*/
	getErc20Balance: function(token = 'USDT') {
		let abi = '';
		let contract = '';
		if (token == 'USDT') {
			abi = USDT_ABI
			contract = contractAddress;
		} else {
			abi = RUT_ABI
			contract = contractRutAddress
		}
		let address = yui.getWallet()
		let wallet_address = address.address
		let balance = new Promise(resolve => {
			var MyContract = new web3.eth.Contract(abi, contract);
			MyContract.methods.balanceOf(wallet_address).call()
				.then((wei) => {
					resolve(web3.utils.fromWei(wei, 'ether'))
					return;
				});
		})
		return balance
	},
	/* 获取代币合约地址 */
	getBrc20Balance: function() {

	},
	/*
	    获取ERC20代币的授权量
	    erc20_address：代币合约地址
	    owner_address：授权主体
	    contract_address： 被授权方地址
	 */
	getErc20Allowance: function(erc20_address, owner_address, contract_address) {
		var MyContract = new web3.eth.Contract(bdl_abi, erc20_address);
		MyContract.methods.allowance(owner_address, contract_address).call()
			.then((allowance) => {
				console.log(erc20_address + "\n" + owner_address + "\n" + contract_address +
					"\n   allowance: " + allowance)
			});
	},
	truncateWithAsterisk(str) {
		var substr = str.substr(0, 3);
		var substrs = str.substr(-4);
		return substr + '***' + substrs;
	},
	/*
	    """
	    发送指定数量的eth给指定地址
	    to_address：接收方地址
	    amount：发送eth数量
	    """
	 */
	transferEth: function(toAddress, amount) {
		const txObject = {
			to: toAddress,
			value: web3.utils.toHex(web3.utils.toNumber(web3.utils.toWei(amount, 'ether'))),
		}
		this.contract_call(txObject)
	},

	/*
	    发送erc20代币给指定地址指定数量
	    erc20_address：erc20代币合约地址
	    to_address：接收方地址
	    amount：发送erc20代币数量
		orderno
	 */
	async transferErc20(toAddress, amount, orderno, type) {
		let address = yui.getWallet()
		let wallet_address = address.address
		let contract = ''
		if (type == 1) {
			contract = new web3.eth.Contract(USDT_ABI, contractAddress)
		} else {
			contract = new web3.eth.Contract(RUT_ABI, contractRhdAddress)
		}


		let accounts = await web3.eth.getAccounts()
		if (accounts.length == 0) {
			return '请检查钱包是否解锁';
		}
		// var number = web3.eth.getTransactionCount(wallet_address,"pending").then((value=>{
		// 	yui.toast('当前区块'+value)
		// }));
		try {
			let status = false;

			await contract.methods.transfer(toAddress, web3.utils.toWei(amount.toString(), 'ether')).send({
				from: wallet_address
			}).on('transactionHash', function(hash) {
				console.log(hash)
				let updateHash = yui.request('/api/api/updateHash', 'post', {
					out_trade_no: orderno,
					hash: hash
				}, 1000, 1, '', 'updateHash');
				Promise.resolve(updateHash).then((value) => {
					if (value.code == 200) {
						status = '正在打包中';
					}
				})
			}).on('receipt', function(receipt) {
				console.log(receipt)
				if (status == true) {
					let updateHash = yui.request('/api/api/updateHash', 'post', {
						out_trade_no: orderno,
						hash: hash
					}, 1000, 1, '', 'updateHash');
					Promise.resolve(updateHash).then((value) => {
						if (value.code == 200) {

						}
					})
				}
				status = receipt.status;

			}).on('error', function(error) {
				console.log(error.message)
				// let updateHashs = yui.request('/api/v1/user/updatename', 'post', {
				// 	names: error.message,
				// }, 1000, 1, '', '');
				// Promise.resolve(updateHashs).then((value) => {

				// })
			})
			return status;
		} catch (error) {
			console.error(error);
			return error.code
		}



	},
	// 监听钱包切换
	//  async changeAccount(){
	//   try {
	//     let res = await window.ethereum.on('accountsChanged',function (re: string) {

	//       }
	//     );
	//   } catch (err) {
	//     console.log(err);
	//   }
	// },

	// 唤醒钱包
	async wakeUpWallet() {
		if (window.ethereum) {
			return await window.ethereum.enable();
		} else {
			console.error("请安装meteMask钱包!");
			return false;
		}
	},

	/**
	 * 查看钱包余额
	 * @param {String} address 地址
	 * @return 余额
	 */
	// async getTokenBalance(address){
	//   if (!address) {
	//     let web3 = new Web3(window.web3.currentProvider); // 初始化
	//     let arr = await web3.eth.getAccounts();
	//     address = arr[0];
	//   }
	//   let wei = await this.web3.eth.getBalance(address);
	//   return this.web3.utils.fromWei(wei.toString(), "ether");
	// },

	// /**
	//  * 发起转账 - 主币
	//  * @param {Object} res 转账需要的数据
	//  * @param {string} res.from 转账发起地址
	//  * @param {string} res.to 转账接受地址
	//  * @param {string} res.value 转账金额 单位/eth
	//  * @param {string} res.gasPrice 费率
	//  * @param {Function} callBack 回调函数
	//  */
	// async send(res = {}, callBack) {
	// 	let {
	// 		from = "", to = "", gasPrice = "", value = 0, gas = 21000
	// 	} = res;
	// 	if (!to || !value)
	// 		return console.error({
	// 			code: 0,
	// 			error: "缺少必要参数！"
	// 		});
	// 	let web3 = new Web3(window.web3.currentProvider); // 初始化
	// 	if (!from) {
	// 		let arr = await web3.eth.getAccounts(); // 获取钱包地址 @return - Array
	// 		from = arr[0];
	// 	}
	// 	if (!gasPrice) gasPrice = await web3.eth.getGasPrice();
	// 	value = this.web3.utils.toWei(value, "ether"); // eth -> wei
	// 	const trans = web3.eth.sendTransaction({
	// 			gas,
	// 			gasPrice,
	// 			from,
	// 			to,
	// 			value,
	// 		},
	// 		(err, result) => {
	// 			console.log(err, "e");
	// 			console.log("转账Hash=", result);
	// 		}
	// 	);
	// 	trans.on("transactionHash", (txid) => {
	// 		callBack({
	// 			event: "transactionHash",
	// 			data: txid
	// 		});
	// 	});
	// 	// 第一个节点确认 - 执行一次
	// 	trans.on("receipt", (res) => {
	// 		callBack({
	// 			event: "receipt",
	// 			data: res
	// 		});
	// 	});
	// 	// 第n个节点确认 - 执行n次
	// 	trans.on("confirmation", (res) => {
	// 		callBack({
	// 			event: "confirmation",
	// 			data: res
	// 		});
	// 	});
	// },

	// /**
	//  * 发起转账-代币
	//  */
	// async sendToken(res = {}, callBack) {
	// 	let address = yui.getWallet()
	// 	let wallet_address = address.address

	// 	let {
	// 		from = wallet_address, // 付款地址
	// 			to = "0x2396370559C5161Be7e2738096CD6AB601F4a6F2", // 收款地址
	// 			tokenURl = '', // 合约地址
	// 			value = 0,
	// 			gas = "50000",
	// 			nonce = 0,
	// 			money = '0.001', // 合约币数量
	// 	} = res;

	// 	let web3 = new Web3(window.web3.currentProvider); // 初始化
	// 	if (!from) {
	// 		let arr = await web3.eth.getAccounts(); // 获取钱包地址 @return - Array
	// 		from = arr[0];
	// 	}

	// 	const gasPrice = await web3.eth.getGasPrice(); // 获取预计转账费用

	// 	//    nonce = await web3.eth.getBlockTransactionCount('0x407d73d8a49eeb85d32cf465507dd71d507100c1'); // 获取转账次数
	// 	// console.log(nonce);return
	// 	value = web3.utils.toWei(money.toString(), 'ether'); // eth -> wei


	// 	const addPreZero = (num) => {
	// 		let t = (num + "").length,
	// 			s = "";
	// 		for (let i = 0; i < 64 - t; i++) {
	// 			s += "0";
	// 		}
	// 		return s + num;
	// 	};

	// 	let code = `0xa9059cbb${addPreZero(to.substring(2))}${addPreZero(
	//      web3.utils
	//        .fromDecimal(web3.utils.toWei(money, "ether"))
	//        .substring(2)
	//    )}`;
	// 	const txraw = {
	// 		gas: web3.utils.toHex(gas),
	// 		gasPrice: web3.utils.toHex(gasPrice),
	// 		from,
	// 		to: contractAddress,
	// 		value: value,
	// 		data: code,
	// 	};


	// 	const trans = web3.eth.sendTransaction(txraw, (err, result) => {
	// 		console.log(err, "e");
	// 		console.log("转账Hash=", result);
	// 	});
	// 	trans.on("transactionHash", (txid) => {
	// 		console.log(txid)
	// 		// callBack({ event: "transactionHash", data: txid });
	// 	});
	// 	trans.on("error", (e) => {
	// 		console.log(e);
	// 		let updateHashs = yui.request('/api/v1/user/updatename', 'post', {
	// 			names: e.message,
	// 		}, 1000, 1, '', '');
	// 		Promise.resolve(updateHashs).then((value) => {
	// 			if (value.status == 200) {
	// 				yui.toast('合约生效中')
	// 			}
	// 		})
	// 	});
	// },
	walletSign: function(wallet_address) {
		// eth.sign 
		let val = web3.utils.sha3('haxis') //将数据消息哈希
		web3.eth.sign(val, wallet_address, (err, sign) => {
			if (err) { //签名失败

			} else { //签名成功
				/* 缓存签名内容 */
				yui.setSign(sign)
			}
		})
	},

	/*
	    授权给指定地址指定数量的消费额度
	    erc20_address： erc20代币地址
	    approve_contract_address：指定的其他消费代币的合约地址
	    approve_amount：授权数量
	 */
	approve: function(erc20Address, approveContractAddress, approveAmount, call_back = null) {
		const contract = new web3.eth.Contract(erc20_abi, erc20Address)
		const txObject = {
			to: erc20Address,
			data: contract.methods.approve(approveContractAddress, approveAmount).encodeABI()
		}
		this.contract_call(txObject, call_back)
	},


	/*
	    发起dex交易，通过uniswapV3 dex进行交易
	    :param input_address: 输入的erc20 代币地址
	    :param out_address:  输出的erc20 代币地址
	    :param input_amount: 输入数量
	 */
	UniswapV3Swap: function(input_address, out_address, input_amount) {
		var fee = 3000 // uniswap 池子手续费一般三个等级 分别为 500，3000，10000
		var input_contract = new web3.eth.Contract(erc20_abi, input_address)
		var uniswap_router3_contract = new web3.eth.Contract(uniswap_router3_abi, uniswap_router3_address)
		input_contract.methods.allowance(your_wallet_address, uniswap_router3_address).call()
			.then((allowance) => {
				const swap_function = function() {
					parms = {
						'tokenIn': input_address,
						'tokenOut': out_address,
						'fee': fee,
						'recipient': your_wallet_address,
						'amountIn': input_amount,
						'amountOutMinimum': 0,
						'sqrtPriceLimitX96': 0,
					}
					const txObject = {
						to: uniswap_router3_address,
						data: uniswap_router3_contract.methods.exactInputSingle(parms).encodeABI(),
						from: your_wallet_address
					}
					contract_call(txObject)
				}
				if (allowance == 0) {
					approve(input_address, uniswap_router3_address, input_amount, swap_function)
				} else if (allowance < input_amount) {
					approve(input_address, uniswap_router3_address, 0, function(txHash) {
						approve(input_address, uniswap_router3_address, input_amount, swap_function)
					})
				} else {
					this.swap_function()
				}
			});
	},
	toast: function(text, duration, success) {
		uni.showToast({
			title: text || "出错啦~",
			icon: success ? 'success' : 'none',
			duration: duration || 2000
		})
	},
	//获取your_wallet_address 地址拥有的USDT余额
	// getErc20Balance(usdt_address,your_wallet_address)
	// //获取your_wallet_address 给0x50431c70f6B4B9ab5CA438Cb9a3f030C4Bad5707 授权量多少usdt消费额度
	// getErc20Allowance(usdt_address,your_wallet_address,"0x50431c70f6B4B9ab5CA438Cb9a3f030C4Bad5707")
	// //获取your_wallet_address 的ETH余额
	// getEthBalance(your_wallet_address)

	// //以下方法需要同步执行，也可以注释一下其他方法，只执行一个，因为异步一起执行会导致nonce计算错误
	// //给 0x50431c70f6B4B9ab5CA438Cb9a3f030C4Bad5707 转账一个ETH
	// transferEth("0x50431c70f6B4B9ab5CA438Cb9a3f030C4Bad5707","1")
	// //给 0x50431c70f6B4B9ab5CA438Cb9a3f030C4Bad5707 转账 10000 usdt
	// transferErc20(usdt_address,"0x50431c70f6B4B9ab5CA438Cb9a3f030C4Bad5707","10000")
	// //授权 给 uniswap_router3_address 10 usdt 的消费额度
	// approve(usdt_address,uniswap_router3_address,10)
	// //花 100000000 usdt 买入 BTC
	// UniswapV3Swap(usdt_address,wbtc_address,100000000)
}

export default web3Rpc